#include <stdio.h>
#include <stdlib.h>

#include "slave.h"
#include "thread_trace.h"
extern __thread_local_fix char traces_id_s[SLAVE_SIZE];
extern __thread_local_fix unsigned long traces_time_s[SLAVE_SIZE / 4];
extern __thread_local_fix int count_s;
extern int total[64];
extern __thread_local_fix char *trace_id;
__thread_local volatile unsigned long trace_put_reply;
extern char traces_id[65][MAXB];
extern unsigned long traces_time[65][MAXB / 4];
/*
int msprintf(char *buff, unsigned long time)
{
    char d;
    int r = 10;
    int i = 0;
    char s[20];
    int j = 0;
    do {
        d = (char)(time % r);
        time /= r;
        s[i++] = d + '0';
    } while (time && i < sizeof(s));
    do {
        buff[j++] = s[--i];

    } while (i);
    buff[j++] = ',';
    buff[j++] = 0;
    return j - 1;
}
*/
void slave_trace_print(unsigned long time, int myid, const char event_name[])
{
    if (4 * total[myid] + 4 <= MAXB) {
        // char trace[16];
        int i = 4 * count_s;
        if (i + 4 <= SLAVE_SIZE) {
            traces_time_s[count_s++] = time;
            if (trace_id[2] == '0') {
                traces_id_s[i] = trace_id[0];
                traces_id_s[i + 1] = trace_id[1];
            } else {
                traces_id_s[i] = '0';
                traces_id_s[i + 1] = trace_id[0];
            }
            traces_id_s[i + 2] = event_name[0];
            traces_id_s[i + 3] = event_name[1];
        } else {
            trace_put_reply = 0;
            athread_put(PE_MODE, &traces_time_s[0], &traces_time[myid + 1][total[myid]],
                        SLAVE_SIZE / 4 * 8, (void *)&trace_put_reply, 0, 0);
            athread_put(PE_MODE, &traces_id_s[0], &traces_id[myid + 1][4 * total[myid]], SLAVE_SIZE,
                        (void *)&trace_put_reply, 0, 0);
            while (trace_put_reply != 2)
                ;
            total[myid] += SLAVE_SIZE / 4;
            count_s = 0;
            i = 0;
            traces_time_s[count_s++] = time;
            if (trace_id[2] == '0') {
                traces_id_s[i] = trace_id[0];
                traces_id_s[i + 1] = trace_id[1];
            } else {
                traces_id_s[i] = '0';
                traces_id_s[i + 1] = trace_id[0];
            }
            traces_id_s[i + 2] = event_name[0];
            traces_id_s[i + 3] = event_name[1];
        }
        /*
        int len = msprintf(trace, time);

        int i;
        if (count_s + len + 6 < SLAVE_SIZE) {
            for (i = count_s; i < count_s + len; i++) {
                trace_s[i] = trace[i - count_s];
            }
            count_s = count_s + len;
            if (trace_id[2] == '0') {
                trace_s[count_s++] = trace_id[0];
                trace_s[count_s++] = trace_id[1];
                trace_s[count_s++] = ',';
            } else {
                trace_s[count_s++] = trace_id[0];
                trace_s[count_s++] = ',';
            }
            if (event_name[0] == '0') {
                trace_s[count_s++] = event_name[1];
                trace_s[count_s++] = ',';
            } else {
                trace_s[count_s++] = event_name[0];
                trace_s[count_s++] = event_name[1];
                trace_s[count_s++] = ',';
            }
        } else {
            trace_put_reply = 0;
            athread_put(PE_MODE, &trace_s[0], &traces[myid + 1][total[myid]], SLAVE_SIZE,
                        (void *)&trace_put_reply, 0, 0);
            while (trace_put_reply != 1)
                ;
            total[myid] += SLAVE_SIZE;
            count_s = 0;
            memset(trace_s, 0, SLAVE_SIZE);
            for (i = count_s; i < count_s + len; i++) {
                trace_s[i] = trace[i - count_s];
            }
            count_s = count_s + len;
            if (trace_id[2] == '0') {
                trace_s[count_s++] = trace_id[0];
                trace_s[count_s++] = trace_id[1];
                trace_s[count_s++] = ',';
            } else {
                trace_s[count_s++] = trace_id[0];
                trace_s[count_s++] = ',';
            }
            if (event_name[0] == '0') {
                trace_s[count_s++] = event_name[1];
                trace_s[count_s++] = ',';
            } else {
                trace_s[count_s++] = event_name[0];
                trace_s[count_s++] = event_name[1];
                trace_s[count_s++] = ',';
            }
        }
        */
    }
}

void slave_trace_print_final(int myid)
{
    if (count_s != 0) {
        trace_put_reply = 0;
        athread_put(PE_MODE, &traces_time_s[0], &traces_time[myid + 1][total[myid]],
                    SLAVE_SIZE / 4 * 8, (void *)&trace_put_reply, 0, 0);
        athread_put(PE_MODE, &traces_id_s[0], &traces_id[myid + 1][4 * total[myid]], SLAVE_SIZE,
                    (void *)&trace_put_reply, 0, 0);
        while (trace_put_reply != 2)
            ;
        total[myid] += count_s;
    }
}
